package dev.bong.aspect;

import dev.bong.annotation.AutoFill;
import dev.bong.constant.AutoFillConstant;
import dev.bong.enumeration.OperationType;
import dev.bong.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @author: bong~
 * @description: TODO
 * @date: 2024/4/11 14:17
 * @version: 1.0
 */

@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    // 切入点：mapper方法且带有AutoFill注解
    @Pointcut("execution(* dev.bong.mapper.*.*(..)) && @annotation(dev.bong.annotation.AutoFill)")
    public void autoFillPoint(){}

    @Before("autoFillPoint()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始自动填充");

        // 获取当前拦截方法上的数据库操作类型（即注解的属性值）
        MethodSignature signature=(MethodSignature)joinPoint.getSignature();
        AutoFill autoFill=signature.getMethod().getAnnotation(AutoFill.class);
        OperationType operationtype = autoFill.value();

        // 获取当前被拦截方法的参数——实体对象
        Object[] args=joinPoint.getArgs();
        if(args==null || args.length==0){
            return;
        }

        Object entity=args[0];

        // 准备赋值的数据
        LocalDateTime now=LocalDateTime.now();
        Map<String,Object> map=ThreadLocalUtil.get();

        Integer userId=(Integer) map.get("userId");
        String currentUser= (String) map.get("username");

        if(operationtype == OperationType.INSERT){

            try{
                Method setCreateTime=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreateBy=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_By, Integer.class);
                Method setUpdateBy=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_BY, Integer.class);

                setCreateTime.invoke(entity, now);
                setUpdateTime.invoke(entity, now);
                setCreateBy.invoke(entity, userId);
                setUpdateBy.invoke(entity, userId);
            }catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }else if(operationtype == OperationType.UPDATE){
            try{
                Method setUpdateTime=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateBy=entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_BY, Integer.class);

                setUpdateTime.invoke(entity, now);
                setUpdateBy.invoke(entity, userId);
            }catch (Exception e){
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }





    }


}
